﻿using QW.Core.Log;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

/*
 * 参考范根的事件代码优化后实现，特别致谢-范根(坑叔)
 */
namespace QW.Core.Events
{
    /// <summary>
    /// 事件总线构建器
    /// </summary>

    public class EventBusBuilder
    {
        private IEventBus  bus;
        private List<EventDetail> Events { get; } = new List<EventDetail>();
        /// <summary>
        /// 构建器
        /// </summary>
        /// <returns></returns>
        public static EventBusBuilder Create()
        {
            return new EventBusBuilder();
        }
        /// <summary>
        /// 注册事件处理器
        /// </summary>
        /// <param name="assemblies"></param>
        /// <returns></returns>
        public EventBusBuilder Register(params string[] assemblies)
        {
            //当前程序所有程序集
            foreach (var assemblyItem in assemblies)
            {
                var assembly = Assembly.Load(assemblyItem);
                var types = assembly.GetTypes().Where(p => p.GetInterface(typeof(IHandler).FullName) != null).ToList();

                foreach (var type in types)
                {
                    var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static);
                    foreach (var method in methods)
                    {
                        var parameters = method.GetParameters();
                        if (parameters.Length != 1) continue;//忽略参数数量不为1的方法
                        var _event = parameters[0];
                        if (_event.ParameterType.GetInterface(typeof(IEvent).FullName) == null) continue;//忽略非事件参数
                        if (method.Name == "Handler")
                        {
                            //处理器执行优先级
                            var attrPriority = method.GetCustomAttribute<EventOrdinalAttribute>();
                            AddHandler(_event.ParameterType, method, attrPriority?.Ordinal ?? 0);
                        }
                        else
                        {
                            LogHandler.Debug($"处理器所有Handler方法名必须为Handler,请检查{type.Name}.{method.Name}");
                        }
                    }
                }
            }
            return this;
        }
        /// <summary>
        /// 注册事件总线
        /// </summary>
        /// <param name="bus"></param>
        /// <returns></returns>
        public EventBusBuilder RegisterBus(IEventBus  bus)
        {
            this.bus = bus;
            return this;
        }
        /// <summary>
        /// 添加处理器
        /// </summary>
        /// <param name="eventType"></param>
        /// <param name="handler"></param>
        /// <param name="priority"></param>
        private void AddHandler(Type eventType, MethodInfo handler, int priority)
        {
            var eventName = eventType.FullName;
            var eventDetail = Events.FirstOrDefault(p => p.EventName == eventName);
            if (eventDetail == null)
            {
                var isDelay = eventType.GetInterface(typeof(IDelayEvent).FullName) != null;
                eventDetail = new EventDetail
                {
                    EventName = eventName,
                    TypeInfo = eventType,
                    IsDelay = isDelay,
                    Handlers = new List<HandlerDetail>()
                };
                Events.Add(eventDetail);
            }
            eventDetail.Handlers.Add(new HandlerDetail
            {
                Ordinal = priority,
                Handler = FastInvoke.GetMethodInvoker(handler)
            });

        }
        /// <summary>
        /// 构建
        /// </summary>
        public void Build()
        {
            foreach (var item in Events)
            {
                item.Handlers = item.Handlers.OrderByDescending(p => p.Ordinal).ToList();
                bus.Subscribe(item);
            }
            EventBus.Register(bus);
        }
    }
}
